from khronos.components import Process
from khronos.primitives import Chain
from khronos.engine import Simulator
from khronos.extra.animation import Animator, Object2D, shape
from math import pi
from random import uniform

ant_shape = shape.list([shape.list([shape.line([(-10, -8), (0, 0)], width=2), 
                                    shape.line([(0, -10), (0, 0)], width=2), 
                                    shape.line([(10, -8), (0, 0)], width=2), 
                                    shape.line([(-10, 8), (0, 0)], width=2), 
                                    shape.line([(0, 10), (0, 0)], width=2), 
                                    shape.line([(10, 8), (0, 0)], width=2)]), 
                        shape.oval(-10, -5, 10, 5), 
                        shape.oval(8, -2, 14, 2), 
                        shape.text(0, 0, fill="lightgreen")])
ant_shape.bind(0, "legs")
ant_shape.bind(1, "torso")
ant_shape.bind(2, "head")
ant_shape.bind(3, "label")

car_shape = shape.list([shape.poly([(-16, 0), (-17, -4), (-8, -5), (-4, -7), 
                                    (4, -7), (10, -5), (17, -4), (16, 0)], fill="black"), 
                        shape.oval(-15, -4, -10, 1, fill="black"), 
                        shape.oval(10, -4, 15, 1, fill="black")])
car_shape.bind(0, "body")
car_shape.bind(1, "backwheel")
car_shape.bind(2, "frontwheel")

class CrazyObject(Process.Atomic, Object2D):
    def __init__(self):
        Process.Atomic.__init__(self)
        Object2D.__init__(self)
        
    @Chain
    def initialize(self):
        sim = self.sim
        speed = 5
        while True:
            yield 1
            self.move_forward(speed)
            self.facing += sim.rng.uniform(-pi/10, pi/10)
            
class CrazyAnt(CrazyObject):
    def __init__(self, color="#FFFFFF", scale=1.0):
        CrazyObject.__init__(self)
        self.shape = ant_shape.copy()
        self.shape["torso"].props.fill = color
        self.shape["head"].props.fill = color
        self.shape["label"].text = self.name
        self.scale = scale
        
class CrazyCar(CrazyObject):
    def __init__(self, color="#FFFFFF", scale=1.0):
        CrazyObject.__init__(self)
        self.shape = car_shape.copy()
        self.shape["body"].props.fill = color
        self.scale = scale
        
sim = Simulator(members=[CrazyCar("blue", uniform(0.25, 4.0)), 
                         CrazyCar("darkgreen", uniform(0.25, 4.0)), 
                         CrazyCar("black", uniform(0.25, 4.0)), 
                         CrazyAnt("red", uniform(0.25, 4.0)), 
                         CrazyAnt("green", uniform(0.25, 4.0)), 
                         CrazyAnt("yellow", uniform(0.25, 4.0)), 
                         CrazyAnt("pink", uniform(0.25, 4.0))])
anim = Animator(sim)

if __name__ == "__main__":
    # This is necessary otherwise the Tk app does not keep the 
    # program alive because it is not using mainloop().
    raw_input()
    
